// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: donggu

#pragma once

#include <memory>
#include <vector>

#include <glog/logging.h>

#include "coin2/exchange/base/executor/actor.h"
#include "coin2/exchange/base/executor/topic_distributor.h"

namespace coin2::exchange::base::executor {

// schedule async actors
class SyncExecutor {
 public:
  explicit SyncExecutor(int thread_num) {
    if (thread_num == 0) {
      topic_distributor_ = std::make_unique<TopicRecordDistributor>();
    } else {
      topic_distributor_ =
          std::make_unique<TopicRecordDistributorMultiThread>(thread_num);
    }
  }
  virtual ~SyncExecutor() = default;

  virtual void Run() = 0;

  TopicRecordDistributor* distributor() { return topic_distributor_.get(); }
  size_t NumSystems() const { return subsystems_.size(); }
  void RegisterSubsystem(ISyncActor* subsystem) { subsystems_.push_back(subsystem); }

  void Prepare() {
    for (auto* actor : subsystems_) {
      actor->Prepare();
    }
  }
  void Cleanup() {
    topic_distributor_->Stop();
    for (auto& actor : subsystems_) {
      actor->Cleanup();
    }
  }

 protected:
  std::unique_ptr<TopicRecordDistributor> topic_distributor_;
  std::vector<ISyncActor*> subsystems_;
};

}  // namespace coin2::exchange::base::executor
